package kd.hc.utils;

import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperateErrorInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDBizException;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class OperationServiceUtil {

    public static OperationResult save(String entityNumber, DynamicObject billData, Boolean isError) {
        OperationResult operationResult = SaveServiceHelper.saveOperate(entityNumber, new DynamicObject[]{billData}, OperateOption.create());
        boolean success = operationResult.isSuccess();
        if (!success && isError) {
            String errorMsg = getOperationResultErrorInfos(operationResult);
            throw new KDBizException(errorMsg);
        }
        return operationResult;
    }

    public static OperationResult submit(String entityNumber, DynamicObject billData, Boolean isError) {
        OperateOption option = OperateOption.create();
        OperationResult operationResult = OperationServiceHelper.executeOperate("submit", entityNumber, new DynamicObject[]{billData}, option);
        boolean success = operationResult.isSuccess();
        if (!success && isError) {
            String errorMsg = getOperationResultErrorInfos(operationResult);
            throw new KDBizException(errorMsg);
        }
        return operationResult;
    }

    public static OperationResult audit(String entityNumber, DynamicObject billData, Boolean isError) {
        OperateOption option = OperateOption.create();
        OperationResult operationResult = OperationServiceHelper.executeOperate("audit", entityNumber, new DynamicObject[]{billData}, option);
        boolean success = operationResult.isSuccess();
        if (!success && isError) {
            String errorMsg = getOperationResultErrorInfos(operationResult);
            throw new KDBizException(errorMsg);
        }
        return operationResult;
    }

    public static OperationResult unaudit(String entityNumber, DynamicObject billData, Boolean isError) {
        OperateOption option = OperateOption.create();
        OperationResult operationResult = OperationServiceHelper.executeOperate("unaudit", entityNumber, new DynamicObject[]{billData}, option);
        boolean success = operationResult.isSuccess();
        if (!success && isError) {
            String errorMsg = getOperationResultErrorInfos(operationResult);
            throw new KDBizException(errorMsg);
        }
        return operationResult;
    }

    public static void delete(String entityNumber, Object pk) {
        MainEntityType entityType = EntityMetadataCache.getDataEntityType(entityNumber);
        DeleteServiceHelper.delete(entityType, new Object[]{pk});
    }

    public static void deleteByOneCondition(String entityNumber, String key, Object value, Boolean isError) {
        OperateOption option = OperateOption.create();
        DynamicObject[] list = BusinessDataServiceHelperExt.loadDyListOneCondition(entityNumber, key, value);
        if (list != null && list.length >= 1) {
            OperationResult operationResult = OperationServiceHelper.executeOperate("unaudit", entityNumber, list, option);
            if (operationResult.isSuccess()) {
                MainEntityType entityType = EntityMetadataCache.getDataEntityType(entityNumber);
                Object[] ids = Arrays.stream(list).map(m1 -> m1.getPkValue()).toArray();
                DeleteServiceHelper.delete(entityType, ids);
            } else {
                if (isError) {
                    String errorMsg = getOperationResultErrorInfos(operationResult);
                    throw new KDBizException(errorMsg);
                }
            }
        }
    }


    public static OperationResult unauditAndDelete(String entityNumber, DynamicObject billData) {
        OperationResult result = unaudit(entityNumber, billData, true);
        if (result.isSuccess()) {
            delete(entityNumber, billData.getPkValue());
        }
        return result;
    }


    public static OperationResult save(String entityNumber, DynamicObject billData) {
        return save(entityNumber, billData, true);
    }

    public static OperationResult submit(String entityNumber, DynamicObject billData) {
        return submit(entityNumber, billData, true);
    }

    public static OperationResult audit(String entityNumber, DynamicObject billData) {
        return audit(entityNumber, billData, true);
    }

    public static OperationResult unaudit(String entityNumber, DynamicObject billData) {
        return unaudit(entityNumber, billData, true);
    }

    public static OperationResult saveAndSubmit(String entityNumber, DynamicObject billData) {
        OperationResult result = save(entityNumber, billData, true);
        if (result.isSuccess()) {
            billData = BusinessDataServiceHelper.loadSingle(result.getSuccessPkIds().get(0), entityNumber);
            result = submit(entityNumber, billData, true);
        }
        return result;
    }

    public static OperationResult saveAndSubmitAndAudit(String entityNumber, DynamicObject billData) {
        OperationResult result = save(entityNumber, billData, true);
        if (result.isSuccess()) {
            billData = BusinessDataServiceHelper.loadSingle(result.getSuccessPkIds().get(0), entityNumber);
            result = submit(entityNumber, billData, true);
            if (result.isSuccess()) {
                billData = BusinessDataServiceHelper.loadSingle(result.getSuccessPkIds().get(0), entityNumber);
                result = audit(entityNumber, billData, true);
            }
        }
        return result;
    }


    public static String getOperationResultErrorInfos(OperationResult operationResult) {
        if (operationResult.isSuccess()) {
            return "";
        }
        List<IOperateInfo> errorInfos = operationResult.getAllErrorOrValidateInfo();
        int size = errorInfos.size() + operationResult.getSuccessPkIds().size();
        if (size > 1) {
            StringBuilder stringBuilder = new StringBuilder();
            int i = 0;
            for (int len = errorInfos.size(); i < 5 && i < len; ++i) {
                stringBuilder.append((errorInfos.get(i)).getMessage());
            }
            return stringBuilder.toString();
        } else if (!errorInfos.isEmpty()) {
            OperateErrorInfo errorInfo = (OperateErrorInfo) errorInfos.get(0);
            String msg = errorInfo.getMessage() == null ? "" : errorInfo.getMessage();
            return msg;
        } else {
            String msg = operationResult.getMessage() == null ? "" : operationResult.getMessage();
            return msg;
        }
    }

}
